/*
 * JVM_Method.h
 *
 *  Created on: 02.01.2011
 *      Author: Tavin
 *
 *  Changed on: 30.04.20011
 *      Author: Dominik Ollesz
 */

#ifndef JVM_METHOD_H_
#define JVM_METHOD_H_

#include "boolean.h"

#include "JVM_DataTypes.h"
#include "JVM_Exception_Handler.h"
#include "JVM_Exceptions.h"

// ACCESS FLAGS
#define ACC_PUBLIC       0x0001
#define ACC_PRIVATE      0x0002
#define ACC_PROTECTED    0x0004
#define ACC_STATIC       0x0008
#define ACC_FINAL        0x0010
#define ACC_SYNCHRONIZED 0x0020
#define ACC_NATIVE       0x0100
#define ACC_ABSTRACT     0x0400
#define ACC_STRICT       0x0800

/**
 * Method Info
 */
typedef struct {

	JVM_Exception_Handler_t* exception_handler;
	uint16_t offset_handlers;     // offset from exception handler address
	uint16_t length_handlers;     // total count of exception handlers

	JVM_Exceptions_t* exceptions;
	uint16_t offset_exceptions;   // offset from exceptions address
	uint16_t length_exceptions;   // total count of exceptions

	uint16_t accesFlags;
	uint16_t nameIndex;
	uint16_t descriptorIndex;
	uint16_t maxStacks;
	uint16_t maxLocals;

	uint16_t codeLenght;
	uint8_t code[];

} JVM_Method_t;






/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_getNameIndex						Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.3			Status : Working   			*/
/*																						*/
/****************************************************************************************/

int static inline JVM_Method_getNameIndex(JVM_Method_t *myMethod)
{
	return(myMethod->nameIndex);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_getDescriptorIndex				Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.3			Status : Working   			*/
/*																						*/
/****************************************************************************************/

int  static inline  JVM_Method_getDescriptorIndex(JVM_Method_t *myMethod)
{
	return(myMethod->descriptorIndex);
}





/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_isPublic					Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.8			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean static inline JVM_Method_isPublic(JVM_Method_t *myMethod)
{
if ((myMethod->accesFlags & ACC_PUBLIC) > 0)
	return(TRUE);

	return(FALSE);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_isPrivate					Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.8			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean static inline JVM_Method_isPrivate(JVM_Method_t *myMethod)
{
if ((myMethod->accesFlags & ACC_PRIVATE)> 0)
	return(TRUE);

	return(FALSE);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_isProtected						Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.8			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean static inline JVM_Method_isProtected(JVM_Method_t *myMethod)
{
if ((myMethod->accesFlags & ACC_PROTECTED)> 0)
	return(TRUE);

	return(FALSE);
}

#define ACC_STATIC  		0x0008

/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_isStatic					Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.8			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean static inline JVM_Method_isStatic(JVM_Method_t *myMethod)
{
if ((myMethod->accesFlags & ACC_STATIC)> 0)
	return(TRUE);

	return(FALSE);
}

#define ACC_FINAL  			0x0010
/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_isSynchronized					Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.8			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean static inline JVM_Method_isSynchronized(JVM_Method_t *myMethod)
{
if ((myMethod->accesFlags & ACC_SYNCHRONIZED)> 0)
	return(TRUE);

	return(FALSE);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_isNative							Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.8			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean static inline JVM_Method_isNative(JVM_Method_t *myMethod)
{
if ((myMethod->accesFlags & ACC_NATIVE)> 0)
	return(TRUE);

	return(FALSE);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_isAbstract						Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.8			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean static inline JVM_Method_isAbstract(JVM_Method_t *myMethod)
{
if ((myMethod->accesFlags & ACC_ABSTRACT)> 0)
	return(TRUE);

	return(FALSE);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_Method_isStrict							Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.8			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean static inline JVM_Method_isStrict(JVM_Method_t *myMethod)
{
if ((myMethod->accesFlags & ACC_STRICT)> 0)
	return(TRUE);

	return(FALSE);
}

//
// Basic exception handling methods
//

/**
 * @author Dominik Ollesz
 */
boolean static inline JVM_Method_throwsException(JVM_Method_t *myMethod) {
	if (myMethod->exceptions != 0) {
		return(TRUE);
	}
	return(FALSE);
}

boolean static inline JVM_Method_hasExceptionHandler(JVM_Method_t *myMethod) {
	return(myMethod->length_handlers != 0);
}

JVM_Exception_Handler_t* JVM_Method_getExceptionHandlerByIndex(JVM_Method_t *myMethod, uint16_t index);
JVM_Exception_Handler_t* JVM_Method_getExceptionHandlerByOffset(JVM_Method_t *myMethod, uint16_t index, uint16_t offset);
short JVM_Method_getExceptionByIndex(JVM_Method_t *myMethod, uint16_t index);
short JVM_Method_getExceptionByOffset(JVM_Method_t *myMethod, uint16_t index, uint16_t offset);


#endif /* JVM_METHOD_H_ */
